﻿using DocumentGeneratorPlugins;
using OpenXmlDocumentGenerator;
using OpenXMLDocumentGenerator.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace OpenXMLDocumentGenerator.Helpers
{
    public static class RenderTypeHelper
    {
        static Type[] types = new Type[] { typeof(string), typeof(int), typeof(short), typeof(uint) };
        public static PropertyModel[] GetPropertyFromObject(object obj, string[] FilterPropertyName)
        {
            List<PropertyModel> lstReturn = new List<PropertyModel>();
            Type t = obj.GetType();
            PropertyInfo[] pis = t.GetProperties();
            foreach (PropertyInfo pi in pis)
            {
                if (FilterPropertyName!=null && FilterPropertyName.Contains(pi.Name))
                    continue;
                if (pi.GetValue(obj) == null)
                    continue;
                PropertyModel pm = new PropertyModel();
                LabelPropertyAttribute[] labelAttributes = (LabelPropertyAttribute[])pi.GetCustomAttributes(typeof(LabelPropertyAttribute), true);
                if (labelAttributes.Length == 0)
                    pm.Name = FormatNameProperty(pi.Name);
                else
                    pm.Name = labelAttributes[0].Label;
                if ((pi.PropertyType != typeof(string) && pi.PropertyType.GetInterfaces().Contains(typeof(System.Collections.IEnumerable)) == true) && pi.PropertyType.Assembly == Assembly.GetExecutingAssembly())
                {
                    List<PropertyModel> lstPM = new List<PropertyModel>();
                    foreach (object o in (System.Collections.IEnumerable)pi.GetValue(obj))
                    {
                        
                        PropertyModel Model = new PropertyModel();
                        Model.Name = " ";
                        Model.Child = GetPropertyFromObject(o, FilterPropertyName);
                        lstPM.Add(Model);
                    }

                    if (lstPM.Count == 0)
                    {
                        pm.Value = " ";
                    }
                    else
                    {
                        pm.Child = lstPM.ToArray();
                    }
                }
                else
                {
                    if (pi.PropertyType.Assembly == Assembly.GetExecutingAssembly())
                        pm.Child = GetPropertyFromObject(pi.GetValue(obj), FilterPropertyName);
                    else if (pi.PropertyType != typeof(string) && pi.PropertyType.GetInterfaces().Contains(typeof(System.Collections.IEnumerable)) == true)
                    {
                        List<string> lstValues = new List<string>();
                        foreach (object o in (System.Collections.IEnumerable)pi.GetValue(obj))
                        {
                            lstValues.Add(o.ToString());
                        }
                        if (lstValues.Count > 0)
                            pm.Values = lstValues.ToArray();
                        else
                            pm.Value = " ";
                    }
                    else
                        pm.Value = pi.GetValue(obj).ToString();
                }
                lstReturn.Add(pm);
            }
            return lstReturn.ToArray();

        }

        private static string FormatNameProperty(string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                return string.Empty;
            StringBuilder newText = new StringBuilder(text.Length * 2);
            newText.Append(text[0]);
            for (int i = 1; i < text.Length; i++)
            {
                if (char.IsUpper(text[i]))
                    if ((text[i - 1] != ' ' && !char.IsUpper(text[i - 1])) || (char.IsUpper(text[i - 1]) &&  i < text.Length - 1 && !char.IsUpper(text[i + 1])))
                        newText.Append(' ');
                newText.Append(text[i]);
            }
            if (string.IsNullOrEmpty(newText.ToString()))
            {
                return string.Empty;
            }
            char[] a = newText.ToString().ToLower().ToCharArray();
            a[0] = char.ToUpper(a[0]);
            return new string(a);

            

        }
        public static void RenderPropertyModelForTable(PropertyModel[] pms,  WordDocumentHelpers wdh)
        {
            string[] strEmpty = new string[] { "" };
            RenderPropertyModelForTable(pms, strEmpty, wdh);
        }
        public static void RenderPropertyModelForTable(PropertyModel[] pms, string[] PropertyToExclude,  WordDocumentHelpers wdh)
        {
            List<List<string>> lstRender = new List<List<string>>();
            List<string> lstRenderHead = new List<string>();
            lstRenderHead.Add("Nom");
            lstRenderHead.Add("Valeur");
            lstRender.Add(lstRenderHead);
            foreach (PropertyModel pm in pms)
            {
                if (PropertyToExclude.Contains(pm.Name))
                    continue;
                List<string> lstRenderProp = new List<string>();
                if (string.IsNullOrWhiteSpace(pm.Value) && pm.Values == null && pm.Child == null)
                    continue;
                lstRenderProp.Add(pm.Name);
                if (pm.Value != null)
                    lstRenderProp.Add(pm.Value);
                if (pm.Values != null)
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (string str in pm.Values)
                        sb.Append(str + "\n");
                    lstRenderProp.Add(sb.ToString());
                }
                if (pm.Child != null)
                {
                    lstRenderProp.Add(RenderPropertyModelForCell(pm.Child));
                }
                lstRender.Add(lstRenderProp);
            }
            wdh.AddTable(TableStyleEnum.StyleGrid2, lstRender);
        }

        public static string RenderPropertyModelForCell(PropertyModel[] propertyModel)
        {
            StringBuilder sb = new StringBuilder();
            foreach (PropertyModel pm in propertyModel)
            {

                if (!string.IsNullOrWhiteSpace(pm.Value))
                {
                    sb.Append(pm.Name + ": " + pm.Value + "\n");

                }
                if ((pm.Values != null) && pm.Values.Count() > 0)
                {

                    foreach (string str in pm.Values)
                    {

                        sb.Append(str + "\n");
                    }
                    sb.Append("\n");
                }
                if (pm.Child != null)
                {
                    sb.Append("-----------\n");
                    sb.Append(pm.Name + "\n");
                    sb.Append(RenderPropertyModelForCell(pm.Child));
                    sb.Append("-----------\n\n");
                }
            }
            sb.Append("\n");
            return sb.ToString();
        }
    }
}
